package org.xmx0632.connector.util.client;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Stopwatch;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * {"code":"0002"}
 * 
 *
 */
public class MultiThreadTcpStressClient implements Runnable {

	public static void main(String[] args) throws Exception {
		int concurrentClientNumber = 1;// client number
		int sendInterval = 1;// ms
		int requestNumberEachClient = 10000;
		CountDownLatch stop = new CountDownLatch(concurrentClientNumber);
		ExecutorService threadPool = Executors.newCachedThreadPool();
		Stopwatch stopwatch = Stopwatch.createUnstarted();
		try {
			System.out.println("clientNumber:" + concurrentClientNumber + " sendInterval:" + sendInterval
					+ " requestNumberEachClient:" + requestNumberEachClient);
			final CountDownLatch begin = new CountDownLatch(1);

			stopwatch.start();
			begin.countDown();
			for (int i = 0; i < concurrentClientNumber; i++) {
				threadPool.execute(new MultiThreadTcpStressClient("localhost", 2003, sendInterval,
						requestNumberEachClient, stop, begin));
				System.out.println("ii:" + i);
			}
			System.out.println("ccccc");
			stop.await();
			System.out.println("dddddccccc");
			long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
			System.out.println("elapsed(ms):" + millis);
			double tps = concurrentClientNumber * requestNumberEachClient * 1000.0 / millis;
			System.out.println("throughput(req/s):" + tps + " when concurrentClientNumber:" + concurrentClientNumber);

		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("111 test finish");
		threadPool.shutdown();
	}

	private final String host;
	private final int port;
	private CountDownLatch stopLatch;
	private int sendInterval;
	private int maxCounter;
	private CountDownLatch beginLatch;

	public MultiThreadTcpStressClient(String host, int port, int sendInterval, int maxCounter, CountDownLatch stopLatch,
			CountDownLatch beginLatch) {
		this.host = host;
		this.port = port;
		this.stopLatch = stopLatch;
		this.sendInterval = sendInterval;
		this.maxCounter = maxCounter;
		this.beginLatch = beginLatch;
	}

	public void run() {
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			beginLatch.await();
			Bootstrap bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class)
					.handler(new TcpClientInitializer(sendInterval, maxCounter));
			bootstrap.connect(host, port).sync().channel();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			group.shutdownGracefully();
			stopLatch.countDown();
		}

	}

}
